import cv2 as cv
import numpy as np
import Reference
import myutils
import matplotlib.pyplot as plt

def showImage(name, image):
    cv.imshow(name, image)
    cv.waitKey(0)
    cv.destroyAllWindows()

idCard = cv.imread("image/credit_card_01.png")
showImage("Ori", idCard)
idCard = myutils.resize(idCard, width=300)
gray = cv.cvtColor(idCard, cv.COLOR_BGR2GRAY)
showImage("Gray", gray)
retm, Binary = cv.threshold(gray, 127, 255, cv.THRESH_BINARY)
showImage("Binary", Binary)
# 定义两个核
rectKernel = cv.getStructuringElement(cv.MORPH_RECT, (9, 3))
rectKerne3 = cv.getStructuringElement(cv.MORPH_RECT, (10, 8))
sqKernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))
#闭运算，连接数字区域
Binary = cv.morphologyEx(Binary, cv.MORPH_CLOSE, rectKerne3)
showImage("binary", Binary)
# 找出所有轮廓
threshCnts_, hierarchy = cv.findContours(Binary.copy(), cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)
cnts = threshCnts_
curimg = idCard.copy()
locs = []# 存储有效轮廓（数字区域）
# 存放识别的数字
output =[]
for cnt in cnts:
    x, y, w, h = cv.boundingRect(cnt)
    # print(cnt.shape())
    ar = w/float(h)
    print("h为"+str(h)+ "w为"+str(w)+"比例为"+str(ar))
    # 由于所有轮廓并不全是数字区域的，所以这里使用长宽以及比例选出数字区域
    # 判断数字区域
    if ar>3.0 and ar<4.0:
        if (w>40 and w<55)and (h>10 and h<20):
            locs.append((x, y, w, h))
# 通过对每隔轮廓的X值，对数字区域的4个轮廓排序，从左到右
locs = sorted(locs, key=lambda x:x[0])

# 银行卡的数字区域一共被分为4块，每块有4个数字，每一个imgROI有4个数字


# 测试代码


# 处理模板
# 输入数字模板图片
referImg = cv.imread("image/ocr_a_reference.png")
# 处理数字模板图片，返回一个字典
dig = Reference.refer(referImg)
# print(dig)

groupOutput = []
# 对4个大的ROI分别处理，灰度，二值化，寻找轮廓，画出轮廓
imgROI = []
for (i, (gX, gY, gW, gH)) in enumerate(locs):
    img = idCard[gY-5:gY+gH+5, gX-5:gX+gW+5]
    imgROI.append(img)

titles = ["1", "2", "3", "4"]
for i in range(4):
    b, g, r = cv.split(imgROI[i])
    imgrgb = cv.merge([r, g, b])
    plt.subplot(2, 3, i + 1), plt.imshow(imgrgb)
    plt.title(titles[i])
plt.show()

for m in range(len(imgROI)):
    fourMumROI = imgROI[m]
    # showImage("demo", imgsplit)
    fourMumROI = cv.cvtColor(fourMumROI, cv.COLOR_BGR2GRAY)
    # showImage("demo", imgsplit)
    fourMumROI = cv.threshold(fourMumROI, 127
                              , 255, cv.THRESH_BINARY
                              )[1]
    # showImage("demo", imgsplit)
    fourNumCnts, imghierarchy = cv.findContours(fourMumROI, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    fourNumImg = imgROI[m]
    # cv.drawContours(imgROI[i], fourNumCnts, -1, (0, 0, 255), 1)
    showImage("demo", imgROI[m])
    fourNumCnts = myutils.sort_contours(fourNumCnts, method="leleft-to-right")[0]
    for (i, c) in enumerate(fourNumCnts):
        (x, y, w, h) = cv.boundingRect(c)
        roi = fourNumImg[y:y + h, x:x + w]
        roi = cv.resize(roi, (57, 88))
        roi = cv.cvtColor(roi, cv.COLOR_BGR2GRAY)
        roi = cv.threshold(roi, 127, 255, cv.THRESH_BINARY)[1]
        showImage("roi", roi)
        # 模板匹配得分情况
        scores = []
        for(digit, digROI) in dig.items():
            result = cv.matchTemplate(roi, digROI, cv.TM_CCOEFF)
            (_, score, _,_)  = cv.minMaxLoc(result)
            scores.append(score)
        groupOutput.append(str(np.argmax(scores)))
        # cv.rectangle(idCard, (gX -5, gY -5), (gX + gW + 5, gY + gH + 5), (0, 0, 255), 1)
        printX, printY, printW, printH = locs[0]
        cv.putText(idCard, "".join(groupOutput), (printX, printY-15), cv.FONT_HERSHEY_SIMPLEX,
                0.65, (0, 0, 255), 2)
    print("".join(groupOutput))
    output.extend(groupOutput)

#

cv.imshow("Image", idCard)
cv.waitKey(0)






# cv.drawContours(curimg, cnts, -1, (0, 0, 255), 3)
# showImage("img", curimg)



# tophat = cv.morphologyEx(gray, cv.MORPH_TOPHAT, rectKernel)
# showImage("tophat", tophat)
# gradX = cv.Sobel(tophat, ddepth=cv.CV_32F, dx=1, dy=0, ksize=-1)
# showImage("sobel", gradX)
# gradX = np.absolute(gradX)
# (minVal, maxVal) = (np.min(gradX), np.max(gradX))
# gradX = (255 * ((gradX - minVal) / (maxVal - minVal)))
# gradX = gradX.astype("uint8")
# showImage("g", gradX)
# gradX = cv.morphologyEx(gradX, cv.MORPH_CLOSE, rectKernel)
# showImage('gradX',gradX)
# thresh = cv.threshold(gradX, 0, 255, cv.THRESH_BINARY|cv.THRESH_OTSU)[1]
# showImage("thresh", thresh)
# thresh = cv.morphologyEx(thresh, cv.MORPH_CLOSE, rectKernel)
# showImage('thresh',thresh)
#
# thresh_, threshCnts, heirarchy = cv.findContours(thresh.coyy(), cv.RETR_EXTERNAL,
#                                                  cv.CHAIN_APPROX_SIMPLE)
# cnts = threshCnts
# cur_img = idCard.copy()
# cv.drawContours(cur_img, cnts, -1, (0, 0, 255), 3)
# showImage("iamge", cur_img)